package org.opens.javaskill.dynamicProxy;

import lombok.Data;
import org.junit.Test;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class DynamicProxyTestUseJdk {

    // 模拟自动装配
    private JdkProxyHandle proxyHandle = new JdkProxyHandle();

    // 模拟自动装配
    private GoodsServiceImpl goodsService = new GoodsServiceImpl();

    /**
     * 功能:
     * <p>jdk的动态代理测试</p>
     * 说明:
     * <pre>
     *     1. jdk的动态代理要求代理对象必须实现一个接口, 然后jdk会基于这个接口进行代理.
     * </pre>
     */
    @Test
    public void test18() {
        proxyHandle.setProxyObject(goodsService);
        // 获取代理对象
        GoodsService proxyService = proxyHandle.getProxy();

        proxyService.sell();
    }

}

interface GoodsService {

    public void sell();

}

class GoodsServiceImpl implements GoodsService {

    @Override
    public void sell() {
        System.out.println("access to database");
    }

}

@Data
class JdkProxyHandle implements InvocationHandler {

    // 代理对象
    private Object proxyObject;

    // 模拟自动装配
    private MyTransactionManagerOne transactionManager = new MyTransactionManagerOne();

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = null;

        try {
            transactionManager.begin();
            result = method.invoke(proxyObject, args);
            transactionManager.commit();
        } catch (Exception e) {
            e.printStackTrace();
            transactionManager.rollback();
        }
        return result;
    }

    /**
     * 功能:
     * <p>获取代理对象</p>
     */
    public <T> T getProxy() {
        return (T) Proxy.newProxyInstance(this.getClass().getClassLoader(), proxyObject.getClass().getInterfaces(), this);
    }

}